#include "mainwindow.h"
#include "shibotu.h"
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QDebug>
#include <QTimer>
#include <QMessageBox>
#include <QStandardItem>
#include <QGridLayout>
#include <QVBoxLayout>
#include <QLineEdit>
bool flag=false;
bool flag_2=false;
//bool flag_3=false;
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    widget = new QWidget();
    this->setCentralWidget(widget);
    sbt.setGeometry(515,100,600,300);
    //布局
    cmbPortName = new QComboBox();
    cmbBaudRate = new QComboBox();
    cmbParity = new QComboBox();
    cmbDataBits = new QComboBox();
    cmbStopBits = new QComboBox();
    cmbFlowControl = new QComboBox();
    btnOpen = new QPushButton(tr("打开串口"));
    teReceiveData = new QTextEdit();
    teReceiveData->setEnabled(false);
    teReceiveData->setFixedHeight(75);
    teSendData = new QTextEdit(tr("abcdefg"));
    teSendData->setFixedHeight(85);
    lPortName = new QLabel(tr("串口号"));
    lBaudRate = new QLabel(tr("波特率"));
    lParity= new QLabel(tr("奇偶校验位"));
    lDataBits= new QLabel(tr("数据位"));
    lStopBits= new QLabel(tr("停止位"));
    lFlowControl = new QLabel(tr("流 控"));
    cbSend = new QCheckBox(tr("HEX发送"));
    cbDisplay = new QCheckBox(tr("HEX显示"));
    cbTimingSend = new QCheckBox(tr("定时发送"));
    letime = new QLineEdit(tr("1000"));
    letime->setFixedSize(40,15);
    lCis = new QLabel(tr("ms/次"));
    lReceiveData = new QLabel(tr("数据接收区"));
    lSendData = new QLabel(tr("数据发送区"));
    btnSend = new QPushButton(tr("发送数据"));
    btnOpenTu = new QPushButton(tr("打开示波图"));


    QGridLayout *leftLayout1 = new QGridLayout(this);
    leftLayout1->addWidget(lPortName,0,0);
    leftLayout1->addWidget(cmbPortName,0,1);
    leftLayout1->addWidget(lBaudRate,1,0);
    leftLayout1->addWidget(cmbBaudRate,1,1);

    leftLayout1->addWidget(lParity,2,0);
    leftLayout1->addWidget(cmbParity,2,1);

    leftLayout1->addWidget(lDataBits,3,0);
    leftLayout1->addWidget(cmbDataBits,3,1);

    leftLayout1->addWidget(lStopBits,4,0);
    leftLayout1->addWidget(cmbStopBits,4,1);

    leftLayout1->addWidget(lFlowControl,5,0);
    leftLayout1->addWidget(cmbFlowControl,5,1);
    leftLayout1->addWidget(cbTimingSend,6,0,2,1);
    leftLayout1->addWidget(letime,7,0);
    leftLayout1->addWidget(lCis,7,1);

    leftLayout1->addWidget(cbSend,8,0);
    leftLayout1->addWidget(cbDisplay,8,1);

    QHBoxLayout *rightfootLayout = new QHBoxLayout(this);
    rightfootLayout->addWidget(btnOpen);
    rightfootLayout->addWidget(btnSend);
    rightfootLayout->addWidget(btnOpenTu);

    QVBoxLayout *rightLayout = new QVBoxLayout(this);
    rightLayout->addWidget(lReceiveData);
    rightLayout->addWidget(teReceiveData);
    rightLayout->addWidget(lSendData);
    rightLayout->addWidget(teSendData);
    rightLayout->addLayout(rightfootLayout);

    QHBoxLayout *mainLayout = new QHBoxLayout(this);
    mainLayout->addLayout(leftLayout1);
    mainLayout->addLayout(rightLayout);
    widget->setLayout(mainLayout);
    setFixedHeight(sizeHint().height());

    /****************************串口初始化*****************************/
    //读取串口信息
    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        //            qDebug()<<"Name:"<<info.portName();
        //            qDebug()<<"Description:"<<info.description();
        //            qDebug()<<"Manufacturer:"<<info.manufacturer();

        //这里相当于自动识别串口号之后添加到了cmb，如果要手动选择可以用下面列表的方式添加进去
        QSerialPort serial;
        serial.setPort(info);
        if(serial.open(QIODevice::ReadWrite))
        {
            //将串口号添加到cmb
            cmbPortName->addItem(info.portName());
            //关闭串口等待人为(打开串口按钮)打开
            serial.close();
        }
    }

    QStringList baudList;//波特率
    QStringList parityList;//校验位
    QStringList dataBitsList;//数据位
    QStringList stopBitsList;//停止位
    QStringList FlowControlList;//流控

    baudList<<"50"<<"75"<<"100"<<"134"<<"150"<<"200"<<"300"
           <<"600"<<"1200"<<"1800"<<"2400"<<"4800"<<"9600"
          <<"14400"<<"19200"<<"38400"<<"56000"<<"57600"
         <<"76800"<<"115200"<<"128000"<<"256000";

    cmbBaudRate->addItems(baudList);
    cmbBaudRate->setCurrentIndex(12);

    parityList<<"无"<<"奇"<<"偶";
    parityList<<"标志";
    parityList<<"空格";

    cmbParity->addItems(parityList);
    cmbParity->setCurrentIndex(0);

    dataBitsList<<"5"<<"6"<<"7"<<"8";
    cmbDataBits->addItems(dataBitsList);
    cmbDataBits->setCurrentIndex(3);

    stopBitsList<<"1";
    stopBitsList<<"1.5";
    stopBitsList<<"2";

    cmbStopBits->addItems(stopBitsList);
    cmbStopBits->setCurrentIndex(0);

    FlowControlList<<"硬控"<<"软控"<<"无"<<"custom";
    cmbFlowControl->addItems(FlowControlList);
    cmbFlowControl->setCurrentIndex(2);
    //设置按钮可以被按下
    //         btnOpen->setCheckable(true);
    myTime = new QTimer();
    myTime->setInterval(1000);
    connect(btnOpen,SIGNAL(clicked()),this,SLOT(on_btnOpen_clicked()));
    connect(btnSend,SIGNAL(clicked()),this,SLOT(on_btnSend_clicked()));
    connect(cbSend,SIGNAL(clicked()),this,SLOT(on_cbSend_clicked()));
    connect(cbDisplay,SIGNAL(clicked()),this,SLOT(on_cbDisplay_clicked()));
    connect(cmbPortName,SIGNAL(currentTextChanged(QString)),this,SLOT(on_cmbPortName_change()));
    connect(myTime,SIGNAL(timeout()),this,SLOT(on_btnSend_clicked()));
    connect(cbTimingSend,SIGNAL(toggled(bool)),this,SLOT(on_cbTimingSend_clicked(bool)));
    connect(btnOpenTu,SIGNAL(clicked()),this,SLOT(on_btnOpenTu_clicked()));
}



MainWindow::~MainWindow()
{

}


/****************************串口设置******************************/
void MainWindow::on_btnOpen_clicked()
{
    if(btnOpen->text() == "打开串口")
    {
        my_serialport = new QSerialPort(this);
        btnOpen->setText(tr("关闭串口"));
        //设置串口号
        my_serialport->setPortName(cmbPortName->currentText());
        //以读写方式打开串口
        if(my_serialport->open(QIODevice::ReadWrite))
        {
            //设置波特率
            my_serialport->setBaudRate(cmbBaudRate->currentText().toInt());
            //设置数据位
            my_serialport->setDataBits(QSerialPort::Data8);
            //设置校验位
            my_serialport->setParity(QSerialPort::NoParity);
            //设置流控制
            my_serialport->setFlowControl(QSerialPort::NoFlowControl);
            //设置停止位
            my_serialport->setStopBits(QSerialPort::OneStop);
            //每秒读一次
            timer = new QTimer(this);
            connect(timer, SIGNAL(timeout()), this, SLOT(readComDataSlot()));
            timer->start(1000);

            //setNonSelectable();
        }
    }
    else
    {
        timer->stop();
        btnOpen->setText("打开串口");
        // setSelectable();
        my_serialport->close();
    }
}

/****************************数据传输******************************/

void MainWindow::on_btnSend_clicked()
{
    QByteArray sendData;
    if(btnOpen->text()=="关闭串口"){
        //获取发送区的数据
//        QString sendData = teSendData->toPlainText();
        if(flag){//十六进制发送
                char cDataHigh,cDataLow;
                int iSendDataSize = 0;
                int iSize = teSendData->toPlainText().size();
                    for(int i = 0;i<iSize-1;)
                    {
                        char tempByte_h =  teSendData->toPlainText().at(i).toLatin1();
                        if(tempByte_h == ' ')
                        {
                            i+=1;
                            continue;
                        }
                        else
                       {
                            char tempByte_l = teSendData->toPlainText().at(i+1).toLatin1();//转化成ASCII码的形式，便于符号之间的运算
                            i+=2;
                            cDataHigh = MainWindow::convertHexFromChar(tempByte_h);
                            cDataLow  = MainWindow::convertHexFromChar(tempByte_l);
                            char sendChar =(char)((cDataHigh<<4)+cDataLow);
                            sendData[iSendDataSize]=sendChar;
                            iSendDataSize++;
                        }
                    }
}
//                    Com->write(sendData);//write是一个重载函数，参考QIODevice类
        else{
            sendData=teSendData->toPlainText().toLatin1();
        }
        //写入缓冲区
       my_serialport->write(sendData);
    }
    else if(btnOpen->text()=="打开串口"){
        QMessageBox::about(NULL, "提示", "串口没有打开！");
        return;
    }

}
/**
 * @brief MainWindow::on_cbSend_clicked
 * 用来判断cbSend复选框所处的状态（是否被勾选）
*/
void MainWindow::on_cbSend_clicked()
{
    flag=!flag;
}
/**
* @brief MainWindow::on_cbDisplay_clicked
* 用来判断cbDisplay复选框所处的状态
*/
void MainWindow::on_cbDisplay_clicked()
{
    flag_2=!flag_2;
}
/**
* @brief MainWindow::on_cmbPortName_change
* 当下拉列表cmbPortName改变时，串口关闭
*/
void MainWindow::on_cmbPortName_change()
{
    if(btnOpen->text()=="关闭串口")
        btnOpen->setText("打开串口");
}
/**
* @brief MainWindow::readComDataSlot
* 读取缓存区的数据
*/
void MainWindow::readComDataSlot()
{
    //接受数据
    QByteArray readComData = my_serialport->readAll();
    QDataStream out(&readComData,QIODevice::ReadWrite);    //将字节数组读入
    if(flag_2){
        while(!out.atEnd())
        {
               qint8 outChar = 0;
               out>>outChar;   //每字节填充一次，直到结束
                   //读取串口数据
               //十六进制的转换
               QString str = QString("%1").arg(outChar&0xFF,2,16,QLatin1Char('0'));
               teReceiveData->insertPlainText(str.toUpper());//大写
               teReceiveData->insertPlainText(" ");//每发送两个字符后添加一个空格
               teReceiveData->moveCursor(QTextCursor::End);
        }
}else{
    if(readComData!=NULL)
        teReceiveData->append(readComData);
        //清除缓冲区
        readComData.clear();
    }

}
/**
* @brief MainWindow::on_cbTimingSend_clicked
* @param checked
* 定时发送数据
*/
void MainWindow::on_cbTimingSend_clicked(bool checked)
{
    if(checked){
        btnSend->setEnabled(false);
        int time = letime->text().toInt();
        myTime->start(time);
    }else{
        myTime->stop();
        btnSend->setEnabled(true);
    }
}
/**
* @brief MainWindow::on_btnOpenTu_clicked
* 打开示波图
*/
void MainWindow::on_btnOpenTu_clicked()
{
    //    this->hide();

    if(btnOpenTu->text()=="打开示波图"){

        btnOpenTu->setText(tr("关闭示波图"));
        sbt.setVisible(true);
        sbt.show();                      // 如果被按下，显示主窗口
        sbt.exec();
    }else{
        btnOpenTu->setText(tr("打开示波图"));
        sbt.hide();
    }
    //        this->show();
}



char  MainWindow::convertHexFromChar(char ch)

{

    if((ch>='0')&&(ch<='9'))

    {

        return(ch-0x30);

    }

    else if((ch>='A')&&(ch<='F'))

    {

        return(ch-'A'+10);

    }

    else if((ch>='a')&&(ch<='f'))

    {

        return(ch-'a'+10);

    }

    else

    {

       return(-1);

    }

}
